package jinyilw.swing.rlaf.ui;

import jinyilw.swing.FontTools;
import jinyilw.swing.graphics.GraphicsTools;
import jinyilw.swing.graphics.RenderingConfig;
import jinyilw.swing.rlaf.theme.RThemeColor;

import javax.swing.BoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicProgressBarUI;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;

/**
 * @author Jinyi
 */
public class RProgressBarUI extends BasicProgressBarUI
{
	// static Stroke largeStroke = new BasicStroke(1.2f);
	private static int barWidth = 6;
	private int offset = 0, offset2 = 0;
	private static Color lightColor = Color.white;

	public static ComponentUI createUI(JComponent c)
	{
		return new RProgressBarUI();
	}

	@Override
	public void installUI(JComponent c)
	{
		super.installUI(c);
		c.setOpaque(false);
		c.setFont(FontTools.defaultFont);
	}

	@Override
	protected void installDefaults()
	{
	}

	@Override
	public void update(Graphics g, JComponent c)
	{
		Insets insets = progressBar.getInsets();
		int x = insets.left + 1;
		int y = insets.top + 1;
		int width = progressBar.getWidth() - (insets.right + insets.left) - 2;
		int height = progressBar.getHeight() - (insets.top + insets.bottom) - 2;
		if (width <= 0 || height <= 0)
			return;
		boolean horizontal = (progressBar
				.getOrientation() == JProgressBar.HORIZONTAL);
		boolean stringPainted = progressBar.isStringPainted();
		int side = Math.min(barWidth, horizontal ? height : width);
		int arc = side, half = side / 2;
		int dx = x, dy = y, dw = width, dh = height;
		int ox = x, oy = y, ow = side, oh = side;
		if (horizontal)
		{
			dy = oy = stringPainted ? height - side : (height - side) / 2;
			dh = side;
			ow = width / 10;
			int oww = width - ow - 12;
			offset2 = (offset2 + half) % oww;
			ox = x + offset2 + 6;
		} else
		{
			dx = ox = (width - side) / 2;
			dw = side;
			oh = height / 10;
			int ohh = height - oh - 12;
			offset2 = (offset2 + half) % ohh;
			oy = height - offset2 - 6;
		}

		Graphics2D g2d = (Graphics2D) g;
		RenderingConfig oldRenderingHints = RenderingConfig
				.enableAAPainting(g2d);

		// paint progress
		int amountFull = 0;
		if (progressBar.isIndeterminate())
		{
			g.setColor(lightColor);
			g.fillRoundRect(ox, oy, ow, oh, arc, arc);
			Color[] colors = RThemeColor.getCircleTransColors();
			offset = (++offset) % colors.length;
			g.setColor(colors[offset]);
			g.fillRoundRect(dx, dy, dw, dh, arc, arc);
		} else
		{
			amountFull = getAmountFull(insets, width, height);
			amountFull = Math.min(amountFull, (horizontal ? width : height));
			int xx = dx, yy = dy, ww = dw, hh = dh;
			if (horizontal)
			{
				if (!c.getComponentOrientation().isLeftToRight())
					xx = dx + (dw - amountFull);
				ww = amountFull;
			} else
			{
				hh = amountFull;
			}
			Color[] colors = RThemeColor.getCircleTransColors();
			offset = (++offset) % colors.length;
			if (isComplete())
				g.setColor(RThemeColor.transThemeColor2);
			else
				g.setColor(colors[offset]);
			g.fillRoundRect(xx, yy, ww, hh, arc, arc);
			//				g.setColor(RThemeColor.darkThemeColor);
			//				g.drawRoundRect(xx, yy, ww, hh, arc, arc);
		}

		g.setColor(RThemeColor.colorSet.borderColor);
		g.drawRoundRect(dx, dy, dw, dh, arc, arc);

		RenderingConfig.resetAAPainting(g2d, oldRenderingHints);

		if (stringPainted)
			paintString(g, x, y, width, height, amountFull, insets);
	}

	private boolean isComplete()
	{
		BoundedRangeModel model = progressBar.getModel();
		return model.getValue() == model.getMaximum();
	}

	@Override
	protected void incrementAnimationIndex()
	{
		progressBar.repaint();
	}

	//	@Override
	//	protected void setAnimationIndex(int newValue)
	//	{
	//		progressBar.repaint();
	//	}

	@Override
	protected void paintString(Graphics g, int x, int y, int width, int height,
			int amountFull, Insets b)
	{
		if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
		{
			if (progressBar.getComponentOrientation().isLeftToRight())
			{
				if (progressBar.isIndeterminate())
				{
					boxRect = getBox(boxRect);
					paintString(g, x, y, width, height, boxRect.x,
							boxRect.width);
				} else
					paintString(g, x, y, width, height, x, amountFull);
			} else
				paintString(g, x, y, width, height, x + width - amountFull,
						amountFull);
		} else
		{
			if (progressBar.isIndeterminate())
			{
				boxRect = getBox(boxRect);
				paintString(g, x, y, width, height, boxRect.y, boxRect.height);
			} else
				paintString(g, x, y, width, height, y + height - amountFull,
						amountFull);
		}
	}

	private void paintString(Graphics g, int x, int y, int w, int h,
			int fillStart, int amountFull)
	{
		Graphics2D g2 = (Graphics2D) g;
		String progressString = progressBar.getString();
		g2.setFont(progressBar.getFont());
		Point renderLocation = getStringPlacement(g2, progressString, x, y, w,
				h);
		Rectangle oldClip = g2.getClipBounds();
		g2.setColor(RThemeColor.colorSet.textColor);
		if (progressBar.getOrientation() == SwingConstants.VERTICAL)
		{
			AffineTransform rotate = AffineTransform
					.getRotateInstance(Math.PI / 2);
			g2.setFont(progressBar.getFont().deriveFont(rotate));
			g2.clipRect(x, fillStart, w, amountFull);
		}
		GraphicsTools.drawSmoothString(g2, progressString, renderLocation.x,
				renderLocation.y);
		//		BasicGraphicsUtils.drawString(progressBar, g2, progressString,
		//				renderLocation.x, renderLocation.y);
		//		SwingUtilities2.drawString(progressBar, g2, progressString,
		//				renderLocation.x, renderLocation.y);
		g2.setClip(oldClip);
	}
}
